package com.yuju.interceptors;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSONObject;
import com.redis.jfinal.plugin.Redis;
import com.yuju.common.Result;
import com.yuju.common.util.collection.CollectionUtilss;
import com.yuju.constant.CacheKey;
import com.yuju.constant.Config;
import com.yuju.enums.ReturnCodeEnum;
import com.yuju.enums.ReturnStatusEnum;
import com.yuju.util.Utils;

/**
 * 
 * 类名：ValidInterceptor  <br />
 *
 * 功能：登录校验拦截器
 *
 * @author : xuehj <br />
 * @Date : 2017年12月13日 下午5:08:44  <br />
 * @version : 1.1 <br />
 */
public class LoginInterceptor implements MethodInterceptor {
	
	private String[] expertLoginUrl = new String[] {"/login/pwdLogin", "/wxLogin/pwdLogin", "/pinCode/send", 
			"/wxLogin/verificationCodeLogin", "/wxLogin/quietLogin", "/wxRegister/register", "/forgetPassword/changePassword", "/wxPay/callback", 
			"/hotel/hotelDropdownList", "/ownerCustom/listOwner", 
			"/hotel/list", "/hotel/selectHotelCity", "/hotel/selectHotelTown", "/roomTypeStatus/getReserveNum",
			"/alipay/callback"};

	/**
	 * 
	 * 功能: 拦截所有Controller中的方法<br/>
	 * 判断该次请求有无token参数，并且检查用户是否已登录，
	 * 已登录，则放行，未登录，则提示需要登录
	 * 
	 * 重写：xuehj <br/>
	 * 
	 * @Date ：2017年12月13日 下午5:09:33<br/>
	 * 
	 * @param invocation
	 * @return
	 * @throws Throwable <br/>
	 * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
	 */
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object[] params = invocation.getArguments();
		Method method = invocation.getMethod();
		System.out.println(method.getName());
		
		if (method.getName().equals("intHttpServlet")) {
			return invocation.proceed();
		}
		
		HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
		
		if (Utils.isNotNull(request)) {
			// 获得用户请求的URI
			String path = request.getRequestURI().replace(request.getContextPath(), "");

			if (CollectionUtilss.contains(expertLoginUrl, path)) {
				return invocation.proceed();
			}
		}
		
		if (Utils.isNotNull(params) && params[0] instanceof JSONObject) {
			System.out.println("param is JSONObject");
			JSONObject obj = (JSONObject) params[0];

			Result result = new Result();
			result.setStatus(ReturnStatusEnum.FAILURE.getCode());
			result.setMsg(ReturnStatusEnum.FAILURE.getDesc());
			result.setReturnCode(ReturnCodeEnum.NO_LOGIN.getCode());
			result.setReturnMsg(ReturnCodeEnum.NO_LOGIN.getDesc());
			
			// 未传递token参数，则返回“需要登录”的信息
			if (Utils.isNull(obj.getString("token"))) {
				return result;
			}
			
			String token = obj.getString("token");
			String userJson = Redis.use().get(token + CacheKey.KEY_CACHE_USER);

			// 如果缓存中无此用户信息，则返回“需要登录”的信息
			if (Utils.isNull(userJson) || userJson.length() <= 0) {
				return result;
			}
			
			// 已经登陆，继续此次请求，并且延长缓存失效时间
			Redis.use().expire(token + CacheKey.KEY_CACHE_USER, Config.CACHE_DEFAULT_TIME_SECONDS);
		}
		return invocation.proceed();
	}

}
